package cn.akwangl.concurrency.web.model.order.service.impl;

import cn.akwangl.concurrency.web.exception.BizException;
import cn.akwangl.concurrency.web.model.order.pojo.OrderVo;
import cn.akwangl.concurrency.web.model.order.pojo.SubmitOrderDto;
import cn.akwangl.concurrency.web.model.order.service.CreateOrdersService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * redis 方式解决线程安全问题.
 *
 * @author 阿坤同学
 * @since 2022-11-27 10:55:53
 */
@Service("redissonOrdersService")
public class RedissonOrdersServiceImpl implements CreateOrdersService {

    private CreateOrdersService createOrdersService;

    private RedissonClient redissonClient;

    @Autowired
    @Qualifier("createOrdersService")
    public void setCreateOrdersService(CreateOrdersService createOrdersService) {
        this.createOrdersService = createOrdersService;
    }

    @Autowired
    public void setRedissonClient(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @Override
    public OrderVo createOrder(SubmitOrderDto submitOrderDto) {
        String redisKey = "order_lock";
        RLock lock = redissonClient.getLock(redisKey);
        try {
            if (lock.tryLock(4000, 1000, TimeUnit.MILLISECONDS)) {
                return createOrdersService.createOrder(submitOrderDto);
            } else {
                throw new BizException("创建订单失败,请重试");
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }
}
